package middlewares

/*
 +----------------------------------------------------------------------
 + Title        : RecoveryMiddleware
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2021-09-22
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : panic错误处理中间件
 +----------------------------------------------------------------------
*/
import (
	"fmt"
	"gomicro-sharemod/gateway-api/tools"
	"net/http"
	"runtime"
	"runtime/debug"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

/**
 * @panic错误处理中间件
 * @author huwl
 * @date 2025/08/05 13:30:24
 */
func RecoveryMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		defer func() {
			if r := recover(); r != nil {
				// 记录 panic 详细信息
				params, _ := tools.GetRequestParams(c)

				// 返回前端友好的 JSON 响应
				data := map[string]interface{}{
					"code":    http.StatusInternalServerError,
					"data":    nil,
					"message": "服务器内部错误",
				}

				// 获取发生 panic 的位置
				_, file, line, ok := runtime.Caller(3)
				if !ok {
					data["message"] = "获取发生 panic 的位置失败"
				}

				tools.Zap.Error("Recovered from panic",
					zap.Int("status", c.Writer.Status()),
					zap.String("file", file),
					zap.Int("line", line),
					zap.String("error", fmt.Sprintf("%v", r)),
					zap.String("method", c.Request.Method),
					zap.String("path", c.Request.URL.Path),
					zap.Any("params", params),
					zap.String("ip", c.ClientIP()),
					zap.String("user-agent", c.Request.UserAgent()),
					zap.String("stack", string(debug.Stack())),
				)

				if tools.Env != "prod" {
					data["error"] = fmt.Sprintf("%v", r)
					data["stack"] = string(debug.Stack())
				}

				c.JSON(http.StatusInternalServerError, data)

				c.Abort()
			}
		}()
		c.Next()
	}
}
